package org.chromium.latency.walt;

import android.content.Context;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class WaltHttp {

    enum TestTypeName
    {
        tap_latency,
        screen_latency,
        drag_latency,
        audio_latency_playback,
        audio_latency_record,
    };

    static Map platformInfo = new HashMap();

    static Context context = null;

    static String urlString = "http://192.168.14.85:8080/latency";

    static void PostJson(Map data){
        data.put("PlatformInfo", platformInfo);
        data.put("FPS", FpsCounter.getInstance().GetFrameFrequency());
        data.put("version", "android");

        try {
            URL url = new URL(urlString);
            HttpURLConnection urlConnection =
                    (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Content-Type", "application/json");

            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.writeValue(urlConnection.getOutputStream(), data);

            final int responseCode = urlConnection.getResponseCode();
            if (responseCode / 100 == 2) {
                Log.i("WaltHttp", "Log successfully uploaded");
            } else {
                Log.e("WaltHttp","Log upload may have failed. Server return status code " + responseCode);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void SetPlatformInfo(Context ctx){
        context = ctx;
        Map info = new HashMap(){{
            put("Vendor", Build.BRAND);
            put("DeviceModel", Build.MODEL);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                put("Chip", Build.SOC_MODEL);
            }
            put("OSInfo", Build.VERSION.RELEASE);
            put("DeviceID", Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID));
        }};
        platformInfo = info;

    }

    static void UploadAudioPlayRes(
            double latency, String ModeStr, int DetectedBeeps, int InitiatedBeeps,
            int FramesPerBuffer, int FrameRate, ArrayList deltasJ2N,
            ArrayList Deltas_Play2Queue, ArrayList Deltas_Queue2Wire){

        Map data = new HashMap(){{
            put("type_name", TestTypeName.audio_latency_playback.toString());
            put("latency", latency);
            put("AudioMode", ModeStr);
            put("DetectedBeeps", DetectedBeeps);
            put("InitiatedBeeps", InitiatedBeeps);
            put("FramesPerBuffer", FramesPerBuffer);
            put("FrameRate", FrameRate);
            put("deltas_J2N", deltasJ2N);
            put("deltas_Play2Queue", Deltas_Play2Queue);
            put("deltas_Queue2Wire", Deltas_Queue2Wire);
        }};
        PostJson(data);
    }

    static void UploadScreenLatency(
            double latency_b2w, double latency_w2b,
            ArrayList deltas, ArrayList deltas_w2b, ArrayList deltas_b2w) {

        Map data = new HashMap() {{
            put("type_name", TestTypeName.screen_latency.toString());
            put("latency_b2w", latency_b2w);
            put("latency_w2b", latency_w2b);
            put("deltas", deltas);
            put("deltas_w2b", deltas_w2b);
            put("deltas_b2w", deltas_b2w);
        }};
        PostJson(data);
    }

    static void UploadTapLatency(
            double latency_down, double latency_up,
             int allDownCount, int allUpCount,
            ArrayList p2kDown, ArrayList k2cDown,
            ArrayList p2kUp, ArrayList k2cUp){

        Map data = new HashMap(){{
                put("type_name", TestTypeName.tap_latency.toString());
                put("latency_down", latency_down);
                put("latency_up", latency_up);
                put("allDownCount", allDownCount);
                put("allUpCount", allUpCount);
                put("p2kDown", p2kDown);
                put("k2cDown", k2cDown);
                put("p2kUp", p2kUp);
                put("k2cUp", k2cUp);
        }};

        PostJson(data);
    }

    static void UploadDragLatency(double Res,
                                  double[] FT, double[] Fy,
                                  double[] LT, int[] Ldir){

        Map data = new HashMap(){{
                put("type_name", TestTypeName.drag_latency.toString());
                put("latency", Res);
                put("finger_time", FT);
                put("finger_pos", Fy);
                put("laser_time", LT);
                put("laser_pos", Ldir);
        }};

        PostJson(data);
    }

    static void UploadAudioRecordRes(double latency, String ModeStr, ArrayList deltas_mic){

        Map data = new HashMap(){{
            put("type_name", TestTypeName.audio_latency_record.toString());
            put("latency", latency);
            put("AudioMode", ModeStr);
            put("deltas_mic", deltas_mic);
	    }};

        PostJson(data);
    }
}
